package multithread.print_by_turn;

import java.util.concurrent.*;

public class CyclicBarriarDemo {
    private static final Integer THREAD_SIZE = 3;
 
    public static void main(String[] args) throws Exception {
        long startTime = System.currentTimeMillis();
        CyclicBarriarDemo cyclicBarriarDemo = new CyclicBarriarDemo();
        int countDownLatchCount = 3; //每次并行处理的线程数
        CountDownLatch countDownLatch = new CountDownLatch(countDownLatchCount);

        ThreadPoolExecutor pool = new ThreadPoolExecutor(THREAD_SIZE, THREAD_SIZE, 0, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());

        int jobCount = 10; // 总共的任务数量
        int lastRunJobcount = jobCount % countDownLatchCount; //最后一次可运行的线程数量
        int cyclicCount = lastRunJobcount == 0? jobCount / countDownLatchCount : (jobCount / countDownLatchCount)+1; // 需要循环次数
        int runCycliCount = 1;// 运行时第几次，从1开始


        for(int i=0; i<jobCount; i++){
            System.out.println("runCycliCount : " + runCycliCount);

            if(cyclicCount == runCycliCount){
                if(lastRunJobcount != 0 && i == ((cyclicCount-1)  * countDownLatchCount)) { //最后一次可运行的线程数量不为0
                    System.out.println("最后一次可运行的线程数量不为0,修改countDownLatch");
                    countDownLatch = new CountDownLatch(lastRunJobcount);
                }else {
                    System.out.println("最后一次可运行的线程数量为0,不处理countDownLatch");
                }
            }

            cyclicBarriarDemo.job(pool, countDownLatch);

            System.out.println("i = " + i);
            if((i+1) % countDownLatchCount == 0){
                countDownLatch.await();
                countDownLatch = new CountDownLatch(countDownLatchCount);
                System.out.println("循环"+runCycliCount+"次");
                runCycliCount = runCycliCount + 1;
            }

            if(i == jobCount - 1){ //运行到最后一次的时候
                if(lastRunJobcount == 0){
                    System.out.println("最后一次可运行数量为0,所有job运行结束");
                }else {
                    countDownLatch.await();
                    System.out.println("循环"+runCycliCount+"次");
                }
            }
        }

        System.out.println("主线程结束");
        pool.shutdown();
        System.out.println(("总耗时: " + (System.currentTimeMillis() - startTime) / 1000) + "s");
    }

    public void job(ThreadPoolExecutor pool, CountDownLatch countDownLatch){
        pool.submit(() -> {
            try {
                Thread.sleep(10000);
                System.out.println("线程: "+Thread.currentThread().getName()+"结束");
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                countDownLatch.countDown();
            }
        });
    }
}